using System;
using System.Collections.Generic;
using LoA.ScreenManager;
using LoA.Shared;
using LoA.Shared.Screen;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace LoA {
	/// <summary>
	/// Sample showing how to manage different game states, with transitions
	/// between menu screens, a loading screen, the game itself, and a pause
	/// menu. This main game class is extremely simple: all the interesting
	/// stuff happens in the ScreenManager component.
	/// </summary>
	public partial class LoAGame : Microsoft.Xna.Framework.Game {
		/// <summary>
		/// The main game constructor.
		/// </summary>
		public LoAGame( ) {
			Config.Initialize( );
			Content.RootDirectory = Config.Get("GameContentDir");

			Engine.DeviceManager = new GraphicsDeviceManager(this);

			//Engine.Settings = new Dictionary<string, string>( );
			Engine.Fonts = new Dictionary<string, SpriteFont>( );
			//Engine.Input = new Dictionary<string, string>( );

			ScreenMenuExporter.Export( );

			//TargetElapsedTime = new TimeSpan((long)(TargetElapsedTime.TotalMilliseconds / 4 * 10000));
			//IsFixedTimeStep = false;

			GameLoader.Initialize( );
		}

		protected override void Initialize( ) {
			this.Window.Title = AppInfo.Title + " " + AppInfo.Version;

			if (this.GraphicsDevice.Adapter.IsProfileSupported(GraphicsProfile.HiDef))
				Engine.DeviceManager.GraphicsProfile = GraphicsProfile.HiDef;
			else
				Engine.DeviceManager.GraphicsProfile = GraphicsProfile.Reach;

			//Engine.DeviceManager.IsFullScreen = true;

			Engine.DeviceManager.PreferMultiSampling = true;

			if (Engine.DeviceManager.IsFullScreen) {
				Engine.DeviceManager.PreferredBackBufferFormat = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Format;
				Engine.DeviceManager.PreferredBackBufferHeight = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
				Engine.DeviceManager.PreferredBackBufferWidth = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;
			}

			Engine.DeviceManager.ApplyChanges( );

			this.IsMouseVisible = true;

			this.GraphicsDevice.Clear(Color.Aqua);

			base.Initialize( );
		}

		/// <summary>
		/// Loads graphics content.
		/// </summary>
		protected override void LoadContent( ) {

			Engine.Fonts.Add("Menu", this.Content.Load<SpriteFont>(@"Font\MenuFont"));

			if (Screen.ScreenManager.Current == null)
				new Screen.ScreenManager(this);
			this.Components.Add(Screen.ScreenManager.Current);
			Screen.ScreenManager.Current.Initialize( );
			Screen.ScreenManager.Current.UpdateOrder = 99;
			Screen.ScreenManager.Current.DrawOrder = 99;

			if (InputEngine.InputComponent.Current == null)
				new InputEngine.InputComponent(this);
			GameLoader.AddGameComponent(InputEngine.InputComponent.Current);
			InputEngine.InputComponent.Current.DrawOrder = 100;
			if (CameraEngine.CameraComponent.Current == null)
				new CameraEngine.CameraComponent(this, InputEngine.InputComponent.Current, WorldSkyEngine.WorldSkyComponent.Current);
			GameLoader.AddGameComponent(CameraEngine.CameraComponent.Current);
			if (PhysicsEngine.PhysicsComponent.Current == null)
				new PhysicsEngine.PhysicsComponent(this, CameraEngine.CameraComponent.Current);
			GameLoader.AddGameComponent(PhysicsEngine.PhysicsComponent.Current);
			if (MapEngine.MapComponent.Current == null)
				new MapEngine.MapComponent(this, CameraEngine.CameraComponent.Current);
			GameLoader.AddGameComponent(MapEngine.MapComponent.Current);
			if (CharacterEngine.CharacterComponent.Current == null)
				new CharacterEngine.CharacterComponent(this, InputEngine.InputComponent.Current, CameraEngine.CameraComponent.Current, MapEngine.MapComponent.Current, PhysicsEngine.PhysicsComponent.Current);
			GameLoader.AddGameComponent(CharacterEngine.CharacterComponent.Current);
			if (GraphicsDevice.GraphicsProfile == GraphicsProfile.HiDef) {
				if (WorldSkyEngine.WorldSkyComponent.Current == null)
					new WorldSkyEngine.WorldSkyComponent(this, CameraEngine.CameraComponent.Current);
				GameLoader.AddGameComponent(WorldSkyEngine.WorldSkyComponent.Current);
			}
			if (GraphicsDevice.GraphicsProfile == GraphicsProfile.HiDef) {
				var lensFlare = new WorldSkyEngine.LensFlareComponent(this, CameraEngine.CameraComponent.Current);
				GameLoader.AddGameComponent(lensFlare);
			}
		}

		protected override void UnloadContent( ) {
			this.Components.Clear( );
			GameLoader.Dispose( );
		}
	}

#if WINDOWS || XBOX
	static class Program {
		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		//[PreEmptive.Attributes.Setup(CustomEndpoint = "so-s.info/PreEmptive.Web.Services.Messaging/MessagingServiceV2.asmx")]
		//[PreEmptive.Attributes.Teardown( )]
		static void Main(string[ ] args) {
			using (LoAGame game = new LoAGame( )) {
				game.Run( );
			}
		}
	}
#endif
}